package com.hmkj.web.controller.my;

import com.hmkj.common.entity.ResultEntity;
import com.hmkj.common.utils.StringUtils;
import com.hmkj.common.utils.ValidateUtils;
import com.hmkj.core.constant.PhoneCodeKey;
import com.hmkj.core.constant.PointNid;
import com.hmkj.core.constant.SessionId;
import com.hmkj.core.exception.BussinessException;
import com.hmkj.core.model.amount.AccountModel;
import com.hmkj.core.model.user.UserModel;
import com.hmkj.core.po.amount.Account;
import com.hmkj.core.po.operate.Agent;
import com.hmkj.core.po.operate.PointRule;
import com.hmkj.core.po.user.User;
import com.hmkj.core.po.user.UserBank;
import com.hmkj.core.service.amount.AccountService;
import com.hmkj.core.service.operate.AgentService;
import com.hmkj.core.service.operate.PointRuleService;
import com.hmkj.core.service.user.UserBankService;
import com.hmkj.core.service.user.UserService;
import com.hmkj.web.controller.GenericController;
import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @author Administrator
 */
@Api(description = "用户中心相关")
@Slf4j
@RestController
@RequestMapping(GenericController.MEMBER_URL + "/user")
public class MyUserController extends GenericController<Integer, User> {

    @Resource
    private UserService userService;
    @Resource
    private UserBankService userBankService;
    @Resource
    private AccountService accountService;
    @Resource
    private PointRuleService pointRuleService;
    @Resource
    private AgentService agentService;

    @ApiOperation(value = "用户是否登录", notes = "用户是否登录")
    @ResponseBody
    @RequestMapping(value = "isLogin", method = RequestMethod.POST)
    public ResultEntity isLogin() {
        return ok();
    }

    @ApiOperation(value = "用户中心首页", notes = "用户中心首页")
    @ResponseBody
    @RequestMapping(value = "index", method = RequestMethod.POST)
    public ResultEntity index() {

        return ok(m -> {
            final User user = userService.selectByPrimaryKey(getLoginUser().getId());
            m.put("id", user.getId());
            m.put("mobile", user.getMobile());
            m.put("avatarUrl", user.getAvatarUrl());
            m.put("point", user.getPoint());
            m.put("userName", user.getUserName());
            m.put("amount", accountService.selectOne(new Account(account -> {
                account.setUserId(user.getId());
                account.setDelFlag(Account.DELFLAG.NORMAL.code);
            })).getAvailable());
            String now = DateUtil.format(new Date(), "yyyyMMdd");
            if (user.getLastSignDate() == null || !now.equals(DateUtil.format(user.getLastSignDate(), "yyyyMMdd"))) {
                m.put("isSign",1);//未签到
            }else{
                m.put("isSign",2);//已签到
            }
        });
    }

    @ApiOperation(value = "用户信息", notes = "用户信息")
    @ResponseBody
    @RequestMapping(value = "userInfo", method = RequestMethod.POST)
    public ResultEntity userInfo() {

        return ok(m -> {
            final User user = userService.selectByPrimaryKey(getLoginUser().getId());
            m.put("id", user.getId());
            m.put("userName", user.getUserName());
            m.put("mobile", user.getMobile());
            m.put("avatarUrl", user.getAvatarUrl());
            m.put("realName", user.getRealName());
            m.put("idCard", user.getIdCard());
            m.put("bindAlipay", StringUtils.isBlank(user.getAlipayAccount()) ? 0 : 1);
            m.put("isSetPayPwd", StringUtils.isBlank(user.getPayPassword()) ? 0 : 1);
            m.put("bankCardSize", userBankService.select(new UserBank(userBank -> {
                userBank.setUserId(user.getId());
                userBank.setStatus(UserBank.STATUS.T3.code);
                userBank.setDelFlag(UserBank.DELFLAG.NORMAL.code);
            })).size());
        });
    }

    @ApiOperation(value = "修改头像", notes = "修改头像 /file/upload接口上传图片后会返回地址,把地址带到这个接口")
    @ResponseBody
    @RequestMapping(value = "avatar", method = RequestMethod.POST)
    public ResultEntity avatar(@ApiParam("头像地址") @RequestParam String avatarUrl) {
        User user = getLoginUser();
        user.setAvatarUrl(avatarUrl);
        setLoginUser(user);
        userService.updateByPrimaryKeySelective(new User(u -> {
            u.setId(user.getId());
            u.setAvatarUrl(avatarUrl);
        }));
        return ok(avatarUrl);
    }

    @ApiOperation(value = "校验密码", notes = "校验密码")
    @ResponseBody
    @RequestMapping(value = "checkPwd", method = RequestMethod.POST)
    public ResultEntity checkPwd(@ApiParam("密码(rsa加密再base64加密)") @RequestParam String oldPwd) {

        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        if (!user.getPassword().equals(UserModel.encodePwd(UserModel.staticDecryptPwd(oldPwd)))) {
            throw new BussinessException("原密码错误");
        }
        return ok();
    }

    @ApiOperation(value = "修改密码", notes = "修改密码")
    @ResponseBody
    @RequestMapping(value = "pwd", method = RequestMethod.POST)
    public ResultEntity pwd(@ApiParam("密码(rsa加密再base64加密)") @RequestParam String oldPwd,
                            @ApiParam("密码(rsa加密再base64加密)") @RequestParam String newPwd) {

        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        if (!user.getPassword().equals(UserModel.encodePwd(UserModel.staticDecryptPwd(oldPwd)))) {
            throw new BussinessException("原密码错误");
        }
        userService.updateByPrimaryKeySelective(new User(u -> {
            u.setId(user.getId());
            u.setPassword(UserModel.encodePwd(UserModel.staticDecryptPwd(newPwd)));
        }));
        return ok();
    }

    @ApiOperation(value = "修改支付密码-校验手机号", notes = "修改支付密码-校验手机号")
    @ResponseBody
    @RequestMapping(value = "phoneSendMsg", method = RequestMethod.POST)
    public ResultEntity phoneSendMsg() throws Exception {
        String domain = getDomain();
        Agent agent = agentService.selectAgentByDomain(domain);
        if (agent != null) {
           sendSmsCode(PhoneCodeKey.RESET_PAY_PWD, getLoginUser().getMobile(),agent.getId());
        } else {
            throw new BussinessException("代理商不存在");
        }
        return ok();
    }

    @ApiOperation(value = "修改支付密码-校验短信", notes = "修改支付密码-校验短信")
    @ResponseBody
    @RequestMapping(value = "phoneCheckPaypwdMsg", method = RequestMethod.POST)
    public ResultEntity phoneCheckPaypwdMsg(@ApiParam("手机短信验证码") @RequestParam String msgCode) throws Exception {
        checkUserPhoneCode(getLoginUser().getMobile(), msgCode, PhoneCodeKey.RESET_PAY_PWD);
        return ok();
    }


    @ApiOperation(value = "校验支付密码", notes = "校验支付密码")
    @ResponseBody
    @RequestMapping(value = "checkPayPwd", method = RequestMethod.POST)
    public ResultEntity payPwd(@ApiParam("密码(rsa加密再base64加密)(未设置支付密码时可空)") @RequestParam String oldPwd) {

        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        if (!user.getPayPassword().equals(UserModel.encodePwd(UserModel.staticDecryptPwd(oldPwd)))) {
            throw new BussinessException("原支付密码错误");
        }
        return ok();
    }

    @ApiOperation(value = "修改/新增支付密码", notes = "修改/新增支付密码")
    @ResponseBody
    @RequestMapping(value = "payPwd", method = RequestMethod.POST)
    public ResultEntity payPwd(@ApiParam("密码(rsa加密再base64加密)(未设置支付密码时可空)") @RequestParam(required = false) String oldPwd,
                               @ApiParam("密码(rsa加密再base64加密)") @RequestParam String newPwd) {

        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        if (StrUtil.isNotBlank(user.getPayPassword()) && !user.getPayPassword().equals(UserModel.encodePwd(UserModel.staticDecryptPwd(oldPwd)))) {
            throw new BussinessException("原支付密码错误");
        }
        userService.updateByPrimaryKeySelective(new User(u -> {
            u.setId(user.getId());
            u.setPayPassword(UserModel.encodePwd(UserModel.staticDecryptPwd(newPwd)));
        }));
        return ok();
    }

    @ApiOperation(value = "手机号验证修改支付密码", notes = "机号验证修改支付密码")
    @ResponseBody
    @RequestMapping(value = "phonePayPwd", method = RequestMethod.POST)
    public ResultEntity phonePayPwd(@ApiParam("密码(rsa加密再base64加密)") @RequestParam String newPwd) {

        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        userService.updateByPrimaryKeySelective(new User(u -> {
            u.setId(user.getId());
            u.setPayPassword(UserModel.encodePwd(UserModel.staticDecryptPwd(newPwd)));
        }));
        return ok();
    }

    @ApiOperation(value = "实名认证", notes = "实名认证")
    @ResponseBody
    @RequestMapping(value = "realName", method = RequestMethod.POST)
    public ResultEntity realName(@ApiParam("真实姓名") @RequestParam String realName,
                                 @ApiParam("身份证号码") @RequestParam String idCard) throws Exception {
        //参数校验
        UserModel.checkRealName(realName, idCard);
        User user = userService.realName(new User(u -> {
            u.setRealName(realName);
            u.setIdCard(idCard);
            u.setId(getLoginUser().getId());
        }));
        setLoginUser(user);
        return ok();
    }

    @ApiOperation(value = "绑定支付宝", notes = "绑定支付宝账号")
    @ResponseBody
    @RequestMapping(value = "bindAlipay", method = RequestMethod.POST)
    public ResultEntity bindAlipay(@ApiParam("身份证号码") @RequestParam String alipayAccount) throws Exception {
        //实名认证校验
        checkRealNameStatus(getLoginUser());
        //参数校验
        UserModel.checkAlipayAccount(alipayAccount);
        User user = userService.bindAlipay(new User(u -> {
            u.setAlipayAccount(alipayAccount);
            u.setId(getLoginUser().getId());
        }));
        setLoginUser(user);
        return ok();
    }


    @ApiOperation(value = "每日签到", notes = "每日签到")
    @ResponseBody
    @RequestMapping(value = "sign", method = RequestMethod.POST)
    public ResultEntity sign() {
        userService.doSign(getLoginUser().getId());
        PointRule pointRule = pointRuleService.selectOne(new PointRule(t ->{
            t.setNid(PointNid.T2.nid);
            t.setStatus(PointRule.STATUS.T1.code);
            t.setDelFlag(PointRule.DELFLAG.NORMAL.code);
        }));
        return ok("签到成功", null == pointRule ? 0:pointRule.getValue());
    }

    @ApiOperation(value = "用户可用/充值限制", notes = "用户可用/充值限制")
    @ResponseBody
    @RequestMapping(value = "rechargeLimit", method = RequestMethod.POST)
    public ResultEntity rechargeLimit() {
        User user = getLoginUser();
        AccountModel accountModel = accountService.getAccountModel(user.getId());
        return ok(m->{
            m.put("rechargeMin", accountModel.getRechargeMin());
            m.put("rechargeMax", accountModel.getRechargeMax());
            m.put("available", accountModel.getAvailable());
        });
    }

    @ApiOperation(value = "修改用户名", notes = "修改用户名")
    @ResponseBody
    @RequestMapping(value = "modifyName", method = RequestMethod.POST)
    public ResultEntity modifyName(@ApiParam("用户名") @RequestParam String userName) throws Exception {
        User user = getLoginUser();
        if (StrUtil.isBlank(userName)) {
            throw new BussinessException("用户名不能为空");
        }else if(userName.length()>50){
            throw new BussinessException("用户名长度不能大于50位！");
        }else if(!ValidateUtils.isUserName(userName)){
            throw new BussinessException("用户名必须是中英文或数字组合");
        }
        if(StringUtils.isNotBlank(user.getUserName())){
            if(user.getUserName().equals(userName)){
                return ok();
            }
        }
        int count = userService.selectCount(new User(t->{
            t.setUserName(userName);
            t.setDelFlag(User.DELFLAG.NORMAL.code);
        }));
        if(count>0){
            throw new BussinessException("该用户名已存在");
        }
        userService.updateByPrimaryKeySelective(new User(u -> {
            u.setId(user.getId());
            u.setUserName(userName);
        }));
        return ok();
    }

    @ApiOperation(value = "修改手机号", notes = "修改手机号")
    @ResponseBody
    @RequestMapping(value = "phone", method = RequestMethod.POST)
    public ResultEntity phone(@ApiParam("老手机短信验证码") @RequestParam String msgCode,
                              @ApiParam("新手机号") @RequestParam String newPhone,
                              @ApiParam("新手机短信验证码") @RequestParam String newMsgCode) {
        final User user = getLoginUser();
        checkUserPhoneCode(getLoginUser().getMobile(), msgCode, PhoneCodeKey.RESET_PHONE);
        checkUserPhoneCode(newPhone, newMsgCode, PhoneCodeKey.RESET_PHONE_NEW);
        userService.updateUserMobile(user.getId(), newPhone);
        delSession(SessionId.RESET_PHONE);
        delSession(SessionId.RESET_PHONE_NEW);
        return ok();
    }

    @ApiOperation(value = "修改手机号-发送短信-老手机短信", notes = "修改手机号-发送短信-老手机短信")
    @ResponseBody
    @RequestMapping(value = "oldPhoneSendMsg", method = RequestMethod.POST)
    public ResultEntity oldPhoneSendMsg() throws Exception {
        String domain = getDomain();
        Agent agent = agentService.selectAgentByDomain(domain);
        if (agent != null) {
            String code = sendSmsCode(PhoneCodeKey.RESET_PHONE, getLoginUser().getMobile(),agent.getId());
            setSession(SessionId.RESET_PHONE, code, 600);// 默认10分钟过期
        } else {
            throw new BussinessException("代理商不存在");
        }
        return ok();
    }

    @ApiOperation(value = "修改手机号-发送短信-新手机短信", notes = "修改手机号-发送短信-新手机短信")
    @ResponseBody
    @RequestMapping(value = "newPhoneSendMsg", method = RequestMethod.POST)
    public ResultEntity newPhoneSendMsg(@ApiParam("新手机号") @RequestParam String newPhone) throws Exception {
        String domain = getDomain();
        Agent agent = agentService.selectAgentByDomain(domain);
        if (agent != null) {
            String code = sendSmsCode(PhoneCodeKey.RESET_PHONE, newPhone,agent.getId());
            setSession(SessionId.RESET_PHONE, code, 600);// 默认10分钟过期
        } else {
            throw new BussinessException("代理商不存在");
        }
        return ok();
    }

    @ApiOperation(value = "修改手机号-校验老手机号短信", notes = "修改手机号-校验老手机号短信")
    @ResponseBody
    @RequestMapping(value = "phoneCheckMsg", method = RequestMethod.POST)
    public ResultEntity phoneCheckMsg(@ApiParam("老手机短信验证码") @RequestParam String msgCode) throws Exception {
        checkUserPhoneCode(getLoginUser().getMobile(), msgCode, PhoneCodeKey.RESET_PHONE);
        return ok();
    }

    @ApiOperation(value = "用户安全等级", notes = "用户安全等级")
    @ResponseBody
    @RequestMapping(value = "safeLevel", method = RequestMethod.POST)
    public ResultEntity safeLevel() throws Exception{
        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        int level = 50;
        //实名认证检查
        if(user.getRealName() != null && user.getIdCard()!= null){
            level = level + 25;
        }
        //是否设置交易密码检查
        if(!StringUtils.isBlank(user.getPayPassword())){
            level = level + 25;
        }
        //计算安全等级 实名、交易密码，每个算25分，<=50，低，<50<=75 中，100 高
        return  ok(level);
    }


}
